package cn.iocoder.yudao.module.lowcode.service.table;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.lowcode.controller.admin.datasource.vo.LowcodeTableInfoRespVO;
import cn.iocoder.yudao.module.lowcode.service.datasource.LowcodeDataSourceConfigService;
import cn.iocoder.yudao.module.lowcode.service.generic.GenericTableServiceEnhancer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 表管理增强服务
 * 演示如何在表操作中集成 Magic API 自动生成功能
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class TableManagementService {

    @Resource
    private GenericTableServiceEnhancer tableServiceEnhancer;
    
    @Resource
    private LowcodeDataSourceConfigService dataSourceConfigService;

    /**
     * 创建新表
     * 示例：演示在建表后自动生成 Magic API 接口
     */
    public void createTable(CreateTableRequest request) {
        try {
            log.info("[createTable] 开始创建表: {}", request.getTableName());
            
            // 1. 执行物理建表操作（这里只是示例，实际需要根据您的建表逻辑实现）
            executeCreateTableSQL(request);
            
            // 2. 表创建成功后，自动生成 Magic API 接口
            tableServiceEnhancer.notifyTableCreated(
                request.getTableName(),
                request.getDataSourceId(),
                request.getTableComment()
            );
            
            log.info("[createTable] 表 {} 创建完成，已自动生成 Magic API 接口", request.getTableName());
            
        } catch (Exception e) {
            log.error("[createTable] 创建表 {} 失败", request.getTableName(), e);
            throw new RuntimeException("创建表失败: " + e.getMessage(), e);
        }
    }

    /**
     * 批量导入表
     * 示例：演示批量导入表后自动生成 Magic API 接口
     */
    public void importTables(ImportTablesRequest request) {
        try {
            log.info("[importTables] 开始批量导入表，共 {} 个", request.getTableNames().size());
            
            int successCount = 0;
            for (String tableName : request.getTableNames()) {
                try {
                    // 1. 执行单个表的导入逻辑
                    importSingleTable(tableName, request.getDataSourceId());
                    
                    // 2. 获取表注释（可选）
                    String tableComment = getTableComment(tableName, request.getDataSourceId());
                    
                    // 3. 为导入的表自动生成 Magic API 接口
                    tableServiceEnhancer.notifyTableCreated(
                        tableName,
                        request.getDataSourceId(),
                        tableComment
                    );
                    
                    successCount++;
                    log.debug("[importTables] 表 {} 导入成功，已生成 Magic API 接口", tableName);
                    
                } catch (Exception e) {
                    log.error("[importTables] 导入表 {} 失败", tableName, e);
                    // 继续处理其他表，不中断整个导入流程
                }
            }
            
            log.info("[importTables] 批量导入完成，成功 {} 个，失败 {} 个", 
                    successCount, request.getTableNames().size() - successCount);
            
        } catch (Exception e) {
            log.error("[importTables] 批量导入表失败", e);
            throw new RuntimeException("批量导入表失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除表
     * 示例：演示删表前自动清理 Magic API 接口
     */
    public void dropTable(DropTableRequest request) {
        try {
            log.info("[dropTable] 开始删除表: {}", request.getTableName());
            
            // 1. 先清理 Magic API 接口（避免产生无效接口）
            tableServiceEnhancer.notifyTableDeleted(
                request.getTableName(),
                request.getDataSourceId(),
                request.getTableComment()
            );
            
            // 2. 再执行物理删表操作
            executeDropTableSQL(request.getTableName(), request.getDataSourceId());
            
            log.info("[dropTable] 表 {} 删除完成，相关 Magic API 接口已清理", request.getTableName());
            
        } catch (Exception e) {
            log.error("[dropTable] 删除表 {} 失败", request.getTableName(), e);
            throw new RuntimeException("删除表失败: " + e.getMessage(), e);
        }
    }

    /**
     * 修改表结构
     * 示例：演示表结构变更后自动更新 Magic API 接口
     */
    public void alterTable(AlterTableRequest request) {
        try {
            log.info("[alterTable] 开始修改表结构: {}", request.getTableName());
            
            // 1. 执行表结构变更操作
            executeAlterTableSQL(request);
            
            // 2. 表结构变更后，自动更新 Magic API 接口
            tableServiceEnhancer.notifyFieldChanged(
                request.getTableName(),
                request.getDataSourceId(),
                request.getTableComment()
            );
            
            log.info("[alterTable] 表 {} 结构修改完成，Magic API 接口已更新", request.getTableName());
            
        } catch (Exception e) {
            log.error("[alterTable] 修改表 {} 结构失败", request.getTableName(), e);
            throw new RuntimeException("修改表结构失败: " + e.getMessage(), e);
        }
    }

    /**
     * 同步数据源中的所有表
     * 示例：演示如何批量同步表并生成对应的 Magic API 接口
     */
    public void syncDataSourceTables(Long dataSourceId) {
        try {
            log.info("[syncDataSourceTables] 开始同步数据源 {} 中的所有表", dataSourceId);
            
            // 1. 获取数据源中的所有表
            List<LowcodeTableInfoRespVO> tables = dataSourceConfigService.getTableInfoList(dataSourceId, null);
            
            if (CollUtil.isEmpty(tables)) {
                log.info("[syncDataSourceTables] 数据源 {} 中没有找到表", dataSourceId);
                return;
            }
            
            // 2. 为每个表生成 Magic API 接口
            int successCount = 0;
            for (LowcodeTableInfoRespVO table : tables) {
                try {
                    tableServiceEnhancer.notifyTableCreated(
                        table.getName(),
                        dataSourceId,
                        table.getComment()
                    );
                    successCount++;
                    
                } catch (Exception e) {
                    log.error("[syncDataSourceTables] 处理表 {} 失败", table.getName(), e);
                }
            }
            
            log.info("[syncDataSourceTables] 数据源 {} 同步完成，共处理 {} 个表，成功 {} 个", 
                    dataSourceId, tables.size(), successCount);
            
        } catch (Exception e) {
            log.error("[syncDataSourceTables] 同步数据源 {} 失败", dataSourceId, e);
            throw new RuntimeException("同步数据源失败: " + e.getMessage(), e);
        }
    }

    // ==================== 私有辅助方法 ====================

    /**
     * 执行建表 SQL（示例方法，需要根据实际情况实现）
     */
    private void executeCreateTableSQL(CreateTableRequest request) {
        // TODO: 实现您的建表逻辑
        log.debug("[executeCreateTableSQL] 执行建表 SQL: {}", request.getTableName());
        
        // 示例：
        // String createSQL = generateCreateTableSQL(request);
        // jdbcTemplate.execute(createSQL);
    }

    /**
     * 执行删表 SQL（示例方法，需要根据实际情况实现）
     */
    private void executeDropTableSQL(String tableName, Long dataSourceId) {
        // TODO: 实现您的删表逻辑
        log.debug("[executeDropTableSQL] 执行删表 SQL: {}", tableName);
        
        // 示例：
        // String dropSQL = "DROP TABLE " + tableName;
        // jdbcTemplate.execute(dropSQL);
    }

    /**
     * 执行表结构变更 SQL（示例方法，需要根据实际情况实现）
     */
    private void executeAlterTableSQL(AlterTableRequest request) {
        // TODO: 实现您的表结构变更逻辑
        log.debug("[executeAlterTableSQL] 执行表结构变更 SQL: {}", request.getTableName());
        
        // 示例：
        // String alterSQL = generateAlterTableSQL(request);
        // jdbcTemplate.execute(alterSQL);
    }

    /**
     * 导入单个表（示例方法，需要根据实际情况实现）
     */
    private void importSingleTable(String tableName, Long dataSourceId) {
        // TODO: 实现您的表导入逻辑
        log.debug("[importSingleTable] 导入表: {}", tableName);
        
        // 示例：从其他数据源复制表结构和数据
        // copyTableFromSource(tableName, dataSourceId);
    }

    /**
     * 获取表注释
     */
    private String getTableComment(String tableName, Long dataSourceId) {
        try {
            List<LowcodeTableInfoRespVO> tables = dataSourceConfigService.getTableInfoList(dataSourceId, tableName);
            return tables.stream()
                    .filter(table -> tableName.equals(table.getName()))
                    .findFirst()
                    .map(table -> table.getComment() != null ? table.getComment() : tableName)
                    .orElse(tableName);
        } catch (Exception e) {
            log.warn("[getTableComment] 获取表 {} 注释失败，使用表名", tableName);
            return tableName;
        }
    }
}